package com.huilian.iotbox.admin.wap.service.impl;

import com.huilian.iotbox.admin.wap.dao.MerchantBannerDao;
import com.huilian.iotbox.admin.wap.service.DeviceService;
import com.huilian.iotbox.admin.wap.service.MerchantBannerService;
import com.huilian.iotbox.admin.wap.service.RabbitSenderService;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.DeviceDto;
import com.huilian.iotbox.data.dto.MerchantBannerDto;
import com.huilian.iotbox.data.enums.DeviceTypeEnum;
import com.huilian.iotbox.data.enums.MerchantBannerTypeEnum;
import com.huilian.iotbox.data.po.MerchantBanner;
import com.huilian.iotbox.data.properties.ImageProperties;
import com.huilian.iotbox.data.service.ErrorLogCommonService;
import com.huilian.iotbox.data.service.UploadService;
import com.huilian.iotbox.data.utils.SnowflakeIdWorker;
import com.huilian.iotbox.data.vo.DeviceVo;
import com.huilian.iotbox.data.vo.MerchantBannerVo;
import com.huilian.iotbox.data.vo.MerchantStoreVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author chenqiwen
 * @CreateDate: 2022-08-18-17-57
 * @Description:
 */
@Slf4j
@Service
public class MerchantBannerServiceImpl implements MerchantBannerService {

    // 最大上传数量
    private static int maxUploadCount = 2;

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private ErrorLogCommonService errorLogCommonService;
    @Autowired
    private ImageProperties imageProperties;
    @Autowired
    private MerchantBannerDao merchantBannerDao;
    @Autowired
    private RabbitSenderService rabbitSenderService;
    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    /**
     * 根据登录用户权限查对应的场地是否有设置广告图
     *
     * @param merchantBannerDto
     * @return
     */
    @Override
    public ServerResponse findMerchantBannerByUserId(MerchantBannerDto merchantBannerDto) {
        List<MerchantStoreVo> merchantBannerList = merchantBannerDao.findMerchantBannerByUserId(merchantBannerDto);
        for (MerchantStoreVo merchantStoreVo : merchantBannerList) {
            if (merchantStoreVo.getMerchantBannersList().size() == 0) {
                merchantStoreVo.setMerchantBannersList(new ArrayList<>());
                continue;
            }

            // 过滤掉状态已删除的
            List<MerchantBanner> list = merchantStoreVo.getMerchantBannersList().stream().filter(item -> {
                return item.getStatus().compareTo(1) == 0;
            }).collect(Collectors.toList());
            merchantStoreVo.setMerchantBannersList(list);
        }
        return ServerResponse.createBySuccess(merchantBannerList);
    }

    /**
     * 根据登录用户权限对应的场地、设备
     *
     * @param deviceDto
     * @param deviceIdArray
     * @return
     */
    @Override
    public List<DeviceVo> findMerchantBannerByDeviceId(DeviceDto deviceDto, Integer[] deviceIdArray) {
        return merchantBannerDao.findMerchantBannerByDeviceId(deviceDto, deviceIdArray);
    }

    /**
     * 根据登录用户权限和场地ID查广告
     *
     * @param merchantBannerDto
     * @return
     */
    @Override
    public ServerResponse findAllMerchantBannerByMerchantStoreId(MerchantBannerDto merchantBannerDto) {

        if (StringUtils.isEmpty(merchantBannerDto.getMerchantStoreId())) {
            return ServerResponse.createByErrorMessage("场地ID不能为空");
        }

        MerchantBannerVo merchantBannerVo = new MerchantBannerVo();

        MerchantBannerDto condition = new MerchantBannerDto();
        condition.setUserInfo(merchantBannerDto.getUserInfo());
        condition.setStatus(1);
        condition.setMerchantStoreId(merchantBannerDto.getMerchantStoreId());

        List<MerchantBanner> merchantTopBannerList = new ArrayList<>();
        List<MerchantBanner> merchantFullScreenBannerList = new ArrayList<>();
        if (StringUtils.isEmpty(merchantBannerDto.getDeviceId())) {
            condition.setType(MerchantBannerTypeEnum.TOP.getCode());
            merchantTopBannerList = merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition);

            condition.setType(MerchantBannerTypeEnum.FULL_SCREEN.getCode());
            merchantFullScreenBannerList = merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition);

        } else {
            condition.setDeviceId(merchantBannerDto.getDeviceId());
            condition.setType(MerchantBannerTypeEnum.TOP_EXCLUSIVE.getCode());
            merchantTopBannerList = merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition);

            condition.setType(MerchantBannerTypeEnum.FULL_EXCLUSIVE.getCode());
            merchantFullScreenBannerList = merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition);
        }
        condition.setType(MerchantBannerTypeEnum.VENDING_MACHINE_TOP.getCode());
        merchantBannerVo.setMerchantVendingMachineTopCarouselList(merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition));
        condition.setType(MerchantBannerTypeEnum.VENDING_MACHINE_FIRST.getCode());
        merchantBannerVo.setMerchantVendingMachineMerchandiseList(merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition));
        condition.setType(MerchantBannerTypeEnum.CLIENT_HOME_ADVERTISING.getCode());
        merchantBannerVo.setMerchantVendingMachineFrontPageList(merchantBannerDao.findAllMerchantBannerByMerchantStoreId(condition));
        merchantBannerVo.setMerchantTopBannerList(merchantTopBannerList);
        merchantBannerVo.setMerchantFullScreenBannerList(merchantFullScreenBannerList);


        return ServerResponse.createBySuccess(merchantBannerVo);
    }


    /**
     * 删除广告图
     *
     * @param merchantBannerDto
     * @return
     */
    @Override
    public ServerResponse deleteMerchantBanner(MerchantBannerDto merchantBannerDto) {

        if (StringUtils.isEmpty(merchantBannerDto.getFileName())) {
            return ServerResponse.createByErrorMessage("删除文件名称失败");
        }

        if (StringUtils.isEmpty(merchantBannerDto.getMerchantStoreId())) {
            return ServerResponse.createByErrorMessage("场地ID不能为空");
        }

        int index = merchantBannerDto.getFileName().lastIndexOf("/");
        if (index == -1) {
            throw new RuntimeException("路径有误，" + merchantBannerDto.getFileName());
        }

        String deleteFileName = merchantBannerDto.getFileName().substring(index + 1);

        MerchantBannerDto condition = new MerchantBannerDto();
        condition.setUserInfo(merchantBannerDto.getUserInfo());
        condition.setFileName(deleteFileName);
        condition.setStatus(1);
        condition.setMerchantStoreId(merchantBannerDto.getMerchantStoreId());
        List<MerchantBanner> merchantBannerList = merchantBannerDao.findAllMerchantBannerByConditionAndPermission(condition);

        for (MerchantBanner merchantBanner : merchantBannerList) {
            if (StringUtils.isEmpty(merchantBanner)) {
                errorLogCommonService.writerInfoErrorLog("删除图片查到没有merchantBannerId", merchantBannerList);
                continue;
            }
            MerchantBanner updateMerchantBanner = new MerchantBanner();
            updateMerchantBanner.setId(merchantBanner.getId());
            updateMerchantBanner.setStatus(0);
            merchantBannerDao.update(updateMerchantBanner);
        }

        return ServerResponse.createBySuccess();
    }

    /**
     * 保存设置广告
     *
     * @param merchantBannerDto
     * @return
     */
    @Override
    public ServerResponse save(MerchantBannerDto merchantBannerDto) {

        if (merchantBannerDto.getTopBannerFileNameList().length == 0
                && merchantBannerDto.getFullScreenBannerFileList().length == 0
                && merchantBannerDto.getVendingMachineTopCarouselFileList().length == 0
                && merchantBannerDto.getVendingMachineMerchandiseFileList().length == 0
                && merchantBannerDto.getVendingMachineFrontPageFileList().length == 0
        ) {
            return ServerResponse.createByErrorMessage("兑币机或售货机至少需新上传一张广告图");
        }

        if (merchantBannerDto.getMerchantStoreIdList().length == 0) {
            return ServerResponse.createByErrorMessage("场地集合不能为空");
        }

        MerchantBannerDto mbDto = new MerchantBannerDto();
        mbDto.setUserInfo(merchantBannerDto.getUserInfo());
        List<MerchantStoreVo> merchantStoreVos = merchantBannerDao.findMerchantBannerByUserId(mbDto);

        int matching = 0;
        for (int i = 0; i < merchantBannerDto.getMerchantStoreIdList().length; i++) {
            Integer merchantStoreId = merchantBannerDto.getMerchantStoreIdList()[i];
            for (MerchantStoreVo merchantStoreVo : merchantStoreVos) {
                if (merchantStoreVo.getId().compareTo(merchantStoreId) == 0) {
                    matching += 1;
                    break;
                }
            }
        }
        if (merchantBannerDto.getMerchantStoreIdList().length != matching) {
            return ServerResponse.createByErrorMessage("部分场地权限不足以设置广告");
        }

        Map<Integer, MerchantStoreVo> merchantStoreVoMap = merchantStoreVos.stream().collect(Collectors.toMap(MerchantStoreVo::getId, a -> a, (k1, k2) -> k1));
        for (Integer merchantBannerId : merchantBannerDto.getMerchantStoreIdList()) {
            MerchantStoreVo merchantStoreVo = merchantStoreVoMap.get(merchantBannerId);
            if (StringUtils.isEmpty(merchantStoreVo)) {
                throw new RuntimeException("场地权限不足以设置广告");
            }
        }

        /**
         * 场景一：单场地设置广告图
         * 场景二：多场地设置广告图
         * 场景三：单场地指定设备设置广告图
         */

        MerchantBanner merchantBannerCondition = new MerchantBanner();
        merchantBannerCondition.setStatus(1);
        if (!StringUtils.isEmpty(merchantBannerDto.getDeviceId())) {
            // 场景三
            DeviceDto deviceDtoCondition = new DeviceDto();
            deviceDtoCondition.setId(merchantBannerDto.getDeviceId());
            DeviceVo deviceVo = null;

            if (merchantBannerDto.getMerchantStoreIdList()[0].compareTo(deviceVo.getMerchantStoreId()) != 0) {
                return ServerResponse.createByErrorMessage("设备权限不足以设置广告");
            }

            if (merchantBannerDto.getTopBannerFileNameList().length > 0) {
                merchantBannerCondition.setType(MerchantBannerTypeEnum.TOP_EXCLUSIVE.getCode());
                this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getTopBannerFileNameList(), merchantBannerDto.getDeviceId(),2);
            }

            if (merchantBannerDto.getFullScreenBannerFileList().length > 0) {
                merchantBannerCondition.setType(MerchantBannerTypeEnum.FULL_EXCLUSIVE.getCode());
                this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getFullScreenBannerFileList(), merchantBannerDto.getDeviceId(),2);
            }
        } else {
            // 场景一、二
            if (merchantBannerDto.getTopBannerFileNameList().length > 0) {
                merchantBannerCondition.setType(MerchantBannerTypeEnum.TOP.getCode());
                this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getTopBannerFileNameList(), null,2);
            }

            if (merchantBannerDto.getFullScreenBannerFileList().length > 0) {
                merchantBannerCondition.setType(MerchantBannerTypeEnum.FULL_SCREEN.getCode());
                this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getFullScreenBannerFileList(), null,2);
            }
        }
        if (merchantBannerDto.getVendingMachineMerchandiseFileList().length  >0 ){
            merchantBannerCondition.setType(MerchantBannerTypeEnum.VENDING_MACHINE_FIRST.getCode());
            this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getVendingMachineMerchandiseFileList(), merchantBannerDto.getDeviceId(),1);
        }
        if (merchantBannerDto.getVendingMachineFrontPageFileList().length  >0 ){
            merchantBannerCondition.setType(MerchantBannerTypeEnum.CLIENT_HOME_ADVERTISING.getCode());
            this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getVendingMachineFrontPageFileList(), merchantBannerDto.getDeviceId(),1);
        }
        if (merchantBannerDto.getVendingMachineTopCarouselFileList().length  >0 ){
            merchantBannerCondition.setType(MerchantBannerTypeEnum.VENDING_MACHINE_TOP.getCode());
            this.common(merchantBannerDto, merchantBannerCondition, merchantBannerDto.getVendingMachineTopCarouselFileList(), merchantBannerDto.getDeviceId(),4);
        }
        return ServerResponse.createBySuccess();
    }

    /**
     * @param merchantBannerDto
     * @param merchantBannerCondition
     * @param fileNameArray
     */
    private void common(MerchantBannerDto merchantBannerDto, MerchantBanner merchantBannerCondition, String[] fileNameArray, Integer deviceId,int maxUploadCount) {

        for (Integer merchantStoreId : merchantBannerDto.getMerchantStoreIdList()) {

            for (int i = 0; i < fileNameArray.length; i++) {
                String key = String.format(RedisKey.FTP_IMAGE_DATE_PROCESSING, fileNameArray[i]);
                redisCacheTemplate.opsForValue().set(key, 1, 15, TimeUnit.MINUTES);
                merchantBannerDao.insert(this.getMerchantBannerFactory(fileNameArray[i], merchantBannerCondition.getType(), merchantStoreId, deviceId));
            }

            merchantBannerCondition.setMerchantStoreId(merchantStoreId);

            /**
             * 上1 原0
             * 上1 原1
             * 上1 原2
             *
             * 上2 原0
             * 上2 原1
             * 上2 原2
             */
            List<MerchantBanner> merchantBannerList = merchantBannerDao.findAllMerchantBannerByCondition(merchantBannerCondition);
            if (merchantBannerList.size() <= maxUploadCount) {
                continue;
            }

            int len = merchantBannerList.size() - maxUploadCount;

            for (int i = 0; i < len; i++) {
                MerchantBanner merchantBanner = merchantBannerList.get(i);
                MerchantBanner updateMerchantBanner = new MerchantBanner();
                updateMerchantBanner.setId(merchantBanner.getId());
                updateMerchantBanner.setStatus(0);
                merchantBannerDao.update(updateMerchantBanner);
            }
        }
    }

    /**
     * 广告对象工厂
     *
     * @param fileName
     * @param type
     * @param merchantStoreId
     * @return
     */
    private MerchantBanner getMerchantBannerFactory(String fileName, int type, int merchantStoreId, Integer deviceId) {
        MerchantBanner merchantBanner = new MerchantBanner();
        merchantBanner.setFileName(fileName);
        merchantBanner.setType(type);
        merchantBanner.setMerchantStoreId(merchantStoreId);
        merchantBanner.setDeviceId(deviceId);
        merchantBanner.setIndex(0);
        merchantBanner.setStatus(1);
        return merchantBanner;
    }


    /**
     * 发消息同步设备信息，包括广告
     */
    @Override
    public ServerResponse findSendAgreement(MerchantBannerDto merchantBannerDto) {
        List<DeviceVo> deviceVoList = new ArrayList<>();
        // 发消息同步设备信息，包括广告
        if (!StringUtils.isEmpty(merchantBannerDto.getDeviceId())) {
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setId(merchantBannerDto.getDeviceId());
            DeviceVo deviceVo = null;

            if (StringUtils.isEmpty(deviceVo) || DeviceTypeEnum.SUPER_MONEY_CHANGER.getCode().compareTo(deviceVo.getDeviceTypeId()) != 0) {
                return ServerResponse.createByErrorMessage("保存失败，设备ID不存在");
            }

            DeviceVo vo = new DeviceVo();
            vo.setId(deviceVo.getId());
            vo.setDeviceNo(deviceVo.getDeviceNo());
            deviceVoList.add(vo);
        } else {

            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setUserInfo(merchantBannerDto.getUserInfo());
            deviceDto.setDeviceTypeId(DeviceTypeEnum.SUPER_MONEY_CHANGER.getCode());
            deviceDto.setMerchantStoreIdList(merchantBannerDto.getMerchantStoreIdList());
            List<DeviceVo> deviceVoList1 = deviceService.findAllDeviceByMerchantStoreIdArray(deviceDto);

            deviceVoList1.forEach(item -> {
                DeviceVo vo = new DeviceVo();
                vo.setId(item.getId());
                vo.setDeviceNo(item.getDeviceNo());
                deviceVoList.add(vo);
            });
        }


        return ServerResponse.createBySuccess(deviceVoList);
    }

}
